import processing.core.*; 
import processing.xml.*; 

import java.applet.*; 
import java.awt.Dimension; 
import java.awt.Frame; 
import java.awt.event.MouseEvent; 
import java.awt.event.KeyEvent; 
import java.awt.event.FocusEvent; 
import java.awt.Image; 
import java.io.*; 
import java.net.*; 
import java.text.*; 
import java.util.*; 
import java.util.zip.*; 
import java.util.regex.*; 

public class Boss extends PApplet {

ParticleSystem ps;

int timeCount = 5;
public void setup()
{
  size(900, 700, P2D);
  //setting = new Settings();
  ps = new ParticleSystem(0, new PVector(0,0));
}

public void draw()
{
  background(255);

  ps.run();
  
  //espiral
  //ps.rotation = frameCount % width;
  ps.rotation = (frameCount % width)*10; //com fator fica mais estreito
  for(int i = 360; i > 0; i--)
    {
      addParticle(i);
    }
  if (frameCount % timeCount == 0) {
      //addRandomParticle();
      /*
    addLinearParticle(Settings.LEFT);
    addLinearParticle(Settings.RIGHT);
    addLinearParticle(Settings.UP);
    addLinearParticle(Settings.DOWN);

    addLinearParticle(Settings.UP_LEFT);
    addLinearParticle(Settings.UP_RIGHT);
    addLinearParticle(Settings.DOWN_LEFT);
    addLinearParticle(Settings.DOWN_RIGHT);*/
    
  }
}

public void addParticle(int i)
{
  Particle p;
  PVector accel = new PVector(cos(radians(i)), sin(radians(i)));
  p = new Particle(ps.origin, accel, new PVector(0, 0), ps.rotation );
  ps.addParticle(p);
}


public void addLinearParticle(int dir)
{
  Particle p;
  PVector accel = new PVector(0, 0);
  float f = 0.05f;
  switch(dir)
  {
  case Settings.LEFT:
    accel.x = -f;
    break;
  case Settings.RIGHT:
    accel.x = f;
    break;
  case Settings.UP:
    accel.y = -f;
    break;
  case Settings.DOWN: 
    accel.y = f; 
    break;

  case Settings.UP_LEFT:
    accel.y = -f;
    accel.x = -f;
    break;
  case Settings.UP_RIGHT:
    accel.y = -f;
    accel.x = f;
    break;
  case Settings.DOWN_LEFT:
    accel.y = f;
    accel.x = -f;
    break;
  case Settings.DOWN_RIGHT:
    accel.y = f;
    accel.x = f;
    break;
  }

  //p = new Particle(ps.origin, accel, new PVector(0, 0), ps.rotation );
  //ps.addParticle(p);
}


public void addRandomParticle()
{
  ps.addParticle();
}



/* CONTROLS
*******************************/

public void keyPressed()
{
  if (key == CODED) {
    if (keyCode == UP) {
      timeCount++;
    } 
    else if (keyCode == DOWN) {
      timeCount-= (timeCount > 1) ? 1 : 0;
    }
  }
}

public void mouseMoved()
{
  //ps.rotation = (mouseX / (float) width) * 90f;
}
// Simple Particle System
// Daniel Shiffman <http://www.shiffman.net>

// A simple Particle class

class Particle {
  PVector location;
  PVector velocity;
  PVector acceleration;
  float lifespan;
  int c;
  float rotation;

  Particle(PVector loc, PVector accel, PVector vel, float rot) {
    acceleration = accel.get();
    velocity = vel.get();
    location = loc.get();
    lifespan = 255.0f;
    c = color(random(50,255), random(50,255), random(50,255));
    rotation = rot;
  }

  public void run() {
    update();
    display();
  }

  // Method to update location
  public void update() {
    velocity.add(acceleration);
    location.add(velocity);
    lifespan -= 3f;
  }

  // Method to display
  public void display() {
    pushMatrix();
    rotate(radians(rotation));
    noStroke();
    //fill(c, lifespan);
    fill(c);
    ellipse(location.x, location.y, 8, 8);
    popMatrix();
  }

  // Is the particle still useful?
  public boolean isDead() {
    if (lifespan < 0.0f) {
      return true;
    } 
    else {
      return false;
    }
  }
}

// Simple Particle System
// Daniel Shiffman <http://www.shiffman.net>

// A class to describe a group of Particles
// An ArrayList is used to manage the list of Particles 

class ParticleSystem {

  ArrayList<Particle> particles;    // An arraylist for all the particles
  PVector origin;        // An origin point for where particles are birthed
  float  rotation = 0;


  ParticleSystem(int num, PVector v) {
    particles = new ArrayList<Particle>();              // Initialize the arraylist
    origin = v.get();      // Store the origin point
    if (num == 0) return;
    for (int i = 0; i < num; i++) {
      particles.add(generateRandomParticle());    // Add "num" amount of particles to the arraylist
    }
  }

  public void run() {
    translate(width/2, height/2);

    Iterator<Particle> it = particles.iterator();

    while (it.hasNext ()) {
      Particle p = it.next();
      if (p.isDead()) {
        it.remove();
      }
      else
      {
        p.run();
      }
    }
  }

  public void addParticle() {
    particles.add(generateRandomParticle());
  }

  public void addParticle(Particle p) {
    particles.add(p);
  }

  public Particle generateRandomParticle()
  {
    return new Particle(origin, new PVector(0, 0.05f), new PVector(random(-1, 1), random(-1, 1)), rotation );
  }

  // A method to test if the particle system still has particles
  public boolean dead() {
    if (particles.isEmpty()) {
      return true;
    } 
    else {
      return false;
    }
  }
}

class Settings{
  final static int LEFT = 1;
  final static int UP = 2;
  final static int RIGHT = 3;
  final static int DOWN = 4;
  final static int UP_LEFT = 5;
  final static int UP_RIGHT = 6;
  final static int DOWN_RIGHT = 7;
  final static int DOWN_LEFT = 8;
  
  Settings(){}
}
  static public void main(String args[]) {
    PApplet.main(new String[] { "--bgcolor=#FFFFFF", "Boss" });
  }
}
